import {
  ApiEditorCompareProjectFoldersReqDto,
  ApiEditorCompareProjectFoldersResDto,
  ResourceChange,
} from '@/types/modules/editor/types/editor.dto';
import { VirtualFileSystem } from '../../../../../../pages/editor/store/VirtualFileSystem';
import { $api } from '@/cross/utils';
import { LcDocument } from '@/types/modules/editor/types/editor.type';
import typeStore from '@/pages/editor/store/type.store';
import { ITypeEntity } from './transformers/ResourceTransform';
import { checkTypeFullyLoaded } from '../utils/entryFactory';

interface IMergeResourceChangesParams {
  projectId: string;
  /**
   * 资源安装本地目录
   */
  rootPath: string;
  remoteProjectId: string;
  /**
   * 远程资源目录
   */
  remotePath: string;
  compareResult: ApiEditorCompareProjectFoldersResDto;
  /**
   * 选中的文件列表
   */
  selectedFiles?: string[];
}

export class FileModuleSystem {
  private static instance: FileModuleSystem;
  private vfs: VirtualFileSystem;

  static getInstance(): FileModuleSystem {
    if (!FileModuleSystem.instance) {
      FileModuleSystem.instance = new FileModuleSystem();
    } else if (!FileModuleSystem.instance) {
      throw new Error('EditorVFSAdapter: projectId is required for first initialization');
    }
    return FileModuleSystem.instance;
  }

  /**
   * 拉取远端文件变化
   */
  public async checkUpdate(params: ApiEditorCompareProjectFoldersReqDto) {
    const checkResult = await $api.post('/editor/compareProjectFolders', params);
    return checkResult;
  }

  public async mergeResourceChanges({
    projectId,
    rootPath,
    remoteProjectId,
    remotePath,
    compareResult,
    selectedFiles,
  }: IMergeResourceChangesParams) {
    // 远程与本地根路径是否一致
    const isSameRootPath = rootPath === remotePath;
    if (!isSameRootPath) {
      // 暂不考虑路径不一致的同步问题
      throw new Error('rootPath and remotePath must be same');
    }
    // 存储类型
    const addTypes: ITypeEntity[] = [];
    const updateTypes: ITypeEntity[] = [];
    const deleteTypes: ITypeEntity[] = [];
    const notFullyLoadedTypeIds: string[] = [];
    const loadedTypeMap: Record<string, ITypeEntity> = {};
    Object.keys(compareResult.changes.types)
      .filter((_id) => {
        if (!selectedFiles) return true;
        return selectedFiles.includes(_id);
      })
      .forEach((_id) => {
        const change = compareResult.changes.types[_id];
        if (change.action !== 'delete') {
          let sourceType = change?.diff.after;
          const isFullyLoaded = checkTypeFullyLoaded(sourceType);
          if (!isFullyLoaded) {
            notFullyLoadedTypeIds.push(sourceType._id);
          }
        }
      });
    // 加载未加载完成的类型
    const loadedTypes = await typeStore.fetchData(
      {
        ids: notFullyLoadedTypeIds,
      },
      false,
      true,
    );
    loadedTypes.forEach((type) => {
      loadedTypeMap[type._id] = type;
    });
    Object.keys(compareResult.changes.types)
      .filter((_id) => {
        if (!selectedFiles) return true;
        return selectedFiles.includes(_id);
      })
      .forEach((_id) => {
        const change = compareResult.changes.types[_id];
        if (change.action === 'delete') {
          deleteTypes.push(change.diff.before);
        } else {
          let sourceType = change?.diff.after;
          if (loadedTypeMap[sourceType._id]) {
            sourceType = loadedTypeMap[sourceType._id];
          }
          const targetType: ITypeEntity = {
            ...sourceType,
            projectId: projectId,
            fkId: projectId,
            from: {
              projectId: sourceType?.projectId,
              typeId: _id,
            },
            unikey: typeStore.getTypeUniKey(sourceType, projectId),
          };
          delete targetType._id;
          if (change.action === 'add') {
            addTypes.push(targetType);
          } else if (change.action === 'modify') {
            updateTypes.push(targetType);
          }
        }
      });

    // 新增或创建文件夹
    const result = await typeStore.syncTypes({
      types: addTypes.concat(updateTypes),
      removeTypes: deleteTypes,
    });
    console.log('syncTypes result: ', result);
  }
}
